﻿using Dapper;
using System;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Web.Bid.Hubs;
using System.Web.UI;
using Web.Bid.Models;
using Web.Bid.Extension;
using System.Configuration;
using System.Data.SqlClient;
using System.Collections.Generic;

namespace Web.Bid
{
    public class Index : Page
    {
        protected int Seconds;
        protected bool Opened;
        protected string JsonData;

        protected int IpAddressLimit=2;
        protected int ConnectionLimit=2;

        protected bool IpAddressLimited;
        protected bool ConnectionLimited;

        protected List<Auction> Auctions;
        protected SilenthinkIdentity Identity;

        protected ConnectionMapping<string> IpAddresses;
        protected ConnectionMapping<string> Connections;

        private readonly string connectionString = ConfigurationManager.ConnectionStrings["SilenthinkAuction"].ConnectionString;

        protected void Page_Load(object sender, EventArgs e)
        {

            var now = DateTime.Now;

            Auctions = new List<Auction>();

            Identity = User.Identity.SkIdentity();

            Opened = AuctionNotifier.Instance.CheckTime(now);

            var closeTime = AuctionNotifier.Instance.CloseTime;

            var tomorrow = Cache.Put("TomorrowAuctions", closeTime, () => GetAuctions(false));

            if (Opened)
            {
                //IpAddresses = AuctionHub.IpAddresses;
                Connections = AuctionHub.Connections;
                if (Connections.GetConnections(User.Identity.Name).Count() > ConnectionLimit-1)
                {
                    Seconds = 0;
                    ConnectionLimited = true;
                }
                else
                {
                    Seconds = (int) closeTime.Subtract(now).TotalSeconds;
                }
                IList<Auction> today;
                if (AuctionNotifier.Instance.MarketState == MarketState.Open)
                {
                    today = AuctionNotifier.Instance.GetAllAuctions();
                }
                else
                {
                    today = GetAuctions();
                }
                JsonData = GetJsonData(today);

                Auctions.AddRange(today);
                Auctions.AddRange(tomorrow);
            }
            else
            {
                var openTime = AuctionNotifier.Instance.OpenTime;
                Seconds = (int)openTime.Subtract(now).TotalSeconds;

                var today = Cache.Put("TodayAuctions", openTime, () => GetAuctions());

                Auctions.AddRange(today);

                Auctions.AddRange(tomorrow);
            }
        }

        private static string GetJsonData(IEnumerable<Auction> today)
        {
            var data = today.ToDictionary(o => o.Id, o => new {
                o.Interval,
                Price = o.CurrentPrice,
                OpenTime = o.StartDateTime,
                CloseTime = o.StopDateTime,
                UserId = o.CurrentUserId,
                NickName = o.CurrentNickName,
                Status=1
            });
            return JsonConvert.SerializeObject(data,new JavaScriptDateTimeConverter());
        }

        internal IList<Auction> GetAuctions(bool today = true)
        {
            var now = DateTime.Now;
            var builder = new SqlBuilder()
                .Field("*").Table("[Auction]")
                .Where("[Status]<=1");

            if (today)
            {
                var time = new DateTime(now.Year, now.Month, now.Day).AddDays(1);
                builder.Where("[OnlineTime]<@time", new { time });
            }
            else
            {
                var begin = new DateTime(now.Year, now.Month, now.Day).AddDays(1);
                var end = new DateTime(now.Year, now.Month, now.Day).AddDays(2);
                builder.Where("[OnlineTime]>=@begin AND [OnlineTime]<@end", new { begin, end });
            }
            var template = builder.AddTemplate(SqlTemplate.Select);
            using (var connection = new SqlConnection(connectionString).EnsureOpen())
            {
                return connection.Query<Auction>(template).ToList();
            }
        }
    }
}